package com.itcam.daijia.driver.service.impl;

import com.alibaba.fastjson.JSON;
import com.itcam.daijia.common.execption.NGException;
import com.itcam.daijia.common.result.ResultCodeEnum;
import com.itcam.daijia.driver.config.TencentCloudProperties;
import com.itcam.daijia.driver.service.CiService;
import com.itcam.daijia.driver.service.CosService;
import com.itcam.daijia.model.vo.driver.CosUploadVo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.*;
import com.qcloud.cos.region.Region;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class CosServiceImpl implements CosService {

    @Autowired
    private CiService ciService;

    @Autowired
    private TencentCloudProperties tencentCloudProperties;


    /**
     * 上传文件到腾讯云COS
     *
     * @param file 要上传的文件
     * @param path 文件上传的路径
     * @return 返回上传文件的信息
     * @throws Exception 如果上传过程中发生异常
     */
    @SneakyThrows
    @Override
    public CosUploadVo upload(MultipartFile file, String path) {
        // 获取私有 COS 客户端
        COSClient cosClient = this.getPrivateCOSClient();

        // 创建元数据对象，设置文件的大小、编码和内容类型
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentLength(file.getSize());
        meta.setContentEncoding("UTF-8");
        meta.setContentType(file.getContentType());

        // 生成上传路径，包括随机文件名和文件后缀
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); // 文件后缀名
        String uploadPath = "/driver/" + path + "/" + UUID.randomUUID().toString().replaceAll("-", "") + fileType;

        // 创建上传请求，设置存储桶、上传路径、文件输入流和元数据
        PutObjectRequest putObjectRequest = new PutObjectRequest(tencentCloudProperties.getBucketPrivate(), uploadPath, file.getInputStream(), meta);
        // 设置存储类型为标准存储
        putObjectRequest.setStorageClass(StorageClass.Standard);

        // 上传文件，并获取上传结果
        PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest); // 上传文件
        // 记录上传结果的日志
        log.info(JSON.toJSONString(putObjectResult));

        // 关闭 COS 客户端连接
        cosClient.shutdown();

        //审核图片
        Boolean isAuditing = ciService.imageAuditing(uploadPath);
        if(!isAuditing) {
            //删除违规图片
            cosClient.deleteObject(tencentCloudProperties.getBucketPrivate(), uploadPath);
            throw new NGException(ResultCodeEnum.IMAGE_AUDITION_FAIL);
        }

        // 封装返回对象，包含上传文件的路径和临时访问 URL
        CosUploadVo cosUploadVo = new CosUploadVo();
        cosUploadVo.setUrl(uploadPath);
        // 图片临时访问url，回显使用
        cosUploadVo.setShowUrl(this.getImageUrl(uploadPath));

        // 返回上传文件的信息
        return cosUploadVo;
    }

    /**
     * 获取图片临时访问URL
     * @param path 文件在COS上的路径
     * @return 临时访问URL，如果路径为空则返回空字符串
     */
    @Override
    public String getImageUrl(String path) {
        // 如果路径为空，则直接返回空字符串
        if (!StringUtils.hasText(path)) return "";

        // 获取私有COS客户端
        COSClient cosClient = getPrivateCOSClient();

        // 创建一个生成预签名URL的请求对象
        GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(tencentCloudProperties.getBucketPrivate(), path, HttpMethodName.GET);

        // 设置临时URL的有效期为15分钟
        Date expiration = new DateTime().plusMinutes(15).toDate();
        request.setExpiration(expiration);

        // 生成临时URL
        URL url = cosClient.generatePresignedUrl(request);

        // 关闭COS客户端
        cosClient.shutdown();

        // 返回临时URL
        return url.toString();
    }


    // ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

    /**
     * 获取私有 COS 客户端
     *
     * @return 返回一个配置好的 COS 客户端对象
     */
    private COSClient getPrivateCOSClient() {
        // 创建一个 COS 凭证对象，使用配置文件中的 SecretId 和 SecretKey
        COSCredentials cred = new BasicCOSCredentials(tencentCloudProperties.getSecretId(), tencentCloudProperties.getSecretKey());
        // 创建一个客户端配置对象，使用配置文件中的 Region
        ClientConfig clientConfig = new ClientConfig(new Region(tencentCloudProperties.getRegion()));
        // 设置客户端配置的 HTTP 协议为 HTTPS
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 创建并返回一个 COS 客户端对象，使用之前创建的凭证和客户端配置
        COSClient cosClient = new COSClient(cred, clientConfig);
        return cosClient;
    }

}
